package site.wlwsjsx.iot_backend.controller;

import com.auth0.jwt.interfaces.DecodedJWT;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import site.wlwsjsx.iot_backend.entity.UserInfo;
import site.wlwsjsx.iot_backend.service.UserService;
import site.wlwsjsx.iot_backend.utils.InputValidationUtil;
import site.wlwsjsx.iot_backend.utils.JWTUtil;
import site.wlwsjsx.iot_backend.utils.JsonResultUtil;
import site.wlwsjsx.iot_backend.utils.SaltEncryptionUtil;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    final
    UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/login")
    public JsonResultUtil<UserInfo> login(@RequestParam String username, @RequestParam String password) {
        log.info("用户登录请求 - 用户名: {}", username);
        JsonResultUtil<UserInfo> result = new JsonResultUtil<>();

        // 验证用户名和密码合法性
        if (!InputValidationUtil.isValidUsername(username)) {
            log.warn("用户登录失败 - 用户名: {}, 原因: 用户名不合法", username);
            result.setState(4000);
            result.setMessage("用户名不合法，只能包含字母、数字和下划线，长度4-20个字符");
            return result;
        }

        if (!InputValidationUtil.isValidPassword(password)) {
            log.warn("用户登录失败 - 用户名: {}, 原因: 密码不合法", username);
            result.setState(4001);
            result.setMessage("密码不合法，至少6个字符，且包含至少一个字母和一个数字");
            return result;
        }

        UserInfo userInfo = userService.findUserByUsername(username);
        if (userInfo == null) {
            log.warn("用户登录失败 - 用户名: {}, 原因: 用户名不存在", username);
            result.setState(4000);
            result.setMessage("用户名不存在");
            return result;
        }

        if (!SaltEncryptionUtil.verifyPassword(password, userInfo.getPassword(), userInfo.getSalt())) {
            log.warn("用户登录失败 - 用户名: {}, 原因: 密码错误", username);
            result.setState(4001);
            result.setMessage("用户名或密码错误");
            return result;
        }

        if (userInfo.getIsDeleted() == true) {
            log.warn("用户登录失败 - 用户名: {}, 原因: 账号已被禁用", username);
            result.setState(4000);
            result.setMessage("用户名不存在");
            return result;
        }

        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("id", String.valueOf(userInfo.getId()));
        tokenMap.put("username", userInfo.getUsername());
        tokenMap.put("role", String.valueOf(userInfo.getRole()));
        String token = JWTUtil.getToken(tokenMap);
        userInfo.setPassword(null);
        userInfo.setSalt(null);

        log.info("用户登录成功 - 用户名: {}, 角色: {}", username, userInfo.getRole());

        result.setState(200);
        result.setMessage("登录成功");
        result.setData(userInfo); // 存储用户基本信息
        result.setToken(token);   // 单独存储token

        return result;
    }

    @PostMapping("/register")
    public JsonResultUtil<UserInfo> register(
            @RequestParam String username,
            @RequestParam String password,
            @RequestParam String realName,
            String phone,
            String email) {
        log.info("用户注册请求 - 用户名: {}", username);
        JsonResultUtil<UserInfo> result = new JsonResultUtil<>();

        // 使用InputValidationUtil验证输入
        if (!InputValidationUtil.isValidUsername(username)) {
            log.warn("用户注册失败 - 用户名: {}, 原因: 用户名不合法", username);
            result.setState(5001);
            result.setMessage("用户名不合法，只能包含字母、数字和下划线，长度4-20个字符");
            return result;
        }

        if (!InputValidationUtil.isValidPassword(password)) {
            log.warn("用户注册失败 - 用户名: {}, 原因: 密码不合法", username);
            result.setState(5002);
            result.setMessage("密码不合法，至少6个字符，且包含至少一个字母和一个数字");
            return result;
        }

        if (!InputValidationUtil.isValidRealName(realName)) {
            log.warn("用户注册失败 - 用户名: {}, 原因: 真实姓名不合法", username);
            result.setState(5003);
            result.setMessage("真实姓名不合法，只能包含中文、英文和空格，长度2-20个字符");
            return result;
        }

        if (!InputValidationUtil.isValidPhone(phone)) {
            log.warn("用户注册失败 - 用户名: {}, 原因: 手机号不合法", username);
            result.setState(5004);
            result.setMessage("手机号不合法");
            return result;
        }

        if (!InputValidationUtil.isValidEmail(email)) {
            log.warn("用户注册失败 - 用户名: {}, 原因: 邮箱不合法", username);
            result.setState(5005);
            result.setMessage("邮箱不合法");
            return result;
        }

        // 校验用户名是否已存在
        UserInfo existingUser = userService.findUserByUsername(username);
        if (existingUser != null) {
            log.warn("用户注册失败 - 用户名: {}, 原因: 用户名已存在", username);
            result.setState(5000);
            result.setMessage("用户名已经被占用");
            return result;
        }

        // 生成盐值和加密密码
        String salt = SaltEncryptionUtil.generateSalt(); // 生成16位盐值
        String encryptedPassword = SaltEncryptionUtil.encryptPassword(password, salt); // 密码加密

        // 构建用户实体
        UserInfo newUser = new UserInfo();
        newUser.setUsername(username);
        newUser.setPassword(encryptedPassword);
        newUser.setSalt(salt);
        newUser.setRole(1); // 默认角色为学生（1=学生，2=管理员）
        newUser.setIsDeleted(true); // 默认正常状态
        newUser.setRealName(realName);
        newUser.setPhone(phone);
        newUser.setEmail(email);

        // 保存用户信息
        int insertResult = userService.txSaveUser(newUser);
        if (insertResult <= 0) {
            log.error("用户注册失败 - 用户名: {}, 原因: 数据库操作失败", username);
            result.setState(404);
            result.setMessage("注册失败");
            return result;
        }

        log.info("用户注册成功 - 用户名: {}, 角色: {}", username, newUser.getRole());

        result.setState(200);
        result.setMessage("注册成功");
        return result;
    }

    @PostMapping("/profile")
    public JsonResultUtil<UserInfo> getUserProfile(HttpServletRequest request) {
        // 从请求头获取token
        String token = request.getHeader("Authorization");
        // 记录请求开始，隐藏token敏感信息
        String maskedToken = token != null ? token.substring(0, Math.min(10, token.length())) + "..." : "null";
        log.info("开始处理获取用户个人信息请求 - token: {}", maskedToken);

        JsonResultUtil<UserInfo> result = new JsonResultUtil<>();

        try {
            // 验证token是否存在
            if (token == null || token.isEmpty()) {
                log.warn("获取用户个人信息失败 - 原因: 缺少认证令牌");
                result.setState(4000);
                result.setMessage("缺少认证令牌");
                return result;
            }

            // 记录token验证开始
            log.debug("开始验证token");

            // 验证token并获取用户信息
            DecodedJWT decodedJWT = JWTUtil.getTokenInfo(token);
            String username = decodedJWT.getClaim("username").asString();

            // 记录从token中提取的用户名
            log.debug("从token中提取用户名: {}", username);

            if (username == null) {
                log.warn("获取用户个人信息失败 - token无效，无法提取用户名");
                result.setState(4000);
                result.setMessage("无效的认证令牌");
                return result;
            }

            // 从数据库获取用户信息
            log.debug("从数据库查询用户名为{}的用户信息", username);
            UserInfo userInfo = userService.findUserByUsername(username);
            if (userInfo == null) {
                log.warn("获取用户个人信息失败 - 用户名: {} 不存在", username);
                result.setState(4000);
                result.setMessage("用户不存在");
                return result;
            }

            // 记录用户ID
            log.debug("找到用户 - ID: {}, 用户名: {}", userInfo.getId(), username);

            if (userInfo.getIsDeleted() == true) {
                log.warn("获取用户个人信息失败 - 用户ID: {} 已被禁用", userInfo.getId());
                result.setState(4000);
                result.setMessage("用户已被禁用");
                return result;
            }

            // 清除敏感信息
            log.debug("清除用户敏感信息（密码和盐值）");
            userInfo.setPassword(null);
            userInfo.setSalt(null);

            // 记录成功获取用户信息
            log.info("成功获取用户个人信息 - 用户ID: {}, 用户名: {}", userInfo.getId(), username);

            result.setState(200);
            result.setMessage("获取个人信息成功");
            result.setData(userInfo);
            return result;
        } catch (Exception e) {
            // 记录详细的错误信息，包括堆栈跟踪
            log.error("获取用户个人信息失败 - token: {}, 错误信息: {}", maskedToken, e.getMessage(), e);
            result.setState(4000);
            result.setMessage("认证失败");
            return result;
        } finally {
            log.debug("获取用户个人信息请求处理结束");
        }
    }
}
